package se.webbzon.oschi01.worldobject.appearance;

import javax.media.j3d.Geometry;
import javax.media.j3d.GeometryArray;
import javax.media.j3d.TriangleStripArray;
import javax.vecmath.Point3d;
import javax.vecmath.TexCoord2f;

import com.sun.j3d.utils.geometry.GeometryInfo;
import com.sun.j3d.utils.geometry.NormalGenerator;

public class WallAppearance3D extends SimpleAppearance3D {
	
	// The geometry model of the wall
	private static final Geometry model = createModel(1,1,1,false);
	
	// The geometry model of the back-faced wall
	private static final Geometry modelBackfaced = createModel(1,1,1,true);

	/*============================================================
	Constructors
	============================================================*/
	
	/** Creates a new WorldObjectWallAppearance. The center of
	 * the wall will be placed in the origin and the wall will
	 * be stretched from (-0.5,-0.5,-0.5) to (0.5,0.5,0.5). **/
	public WallAppearance3D() {
		this(0,0,false);
	}
	
	/** Creates a new WorldObjectWallAppearance. The center of
	 * the wall will be placed in the origin and the wall will
	 * be stretched from (-0.5,-0.5,-0.5) to (0.5,0.5,0.5).
	 * See WorldObjectSimpleAppearance for full description of 
	 * the attributes renderingOrder and simpleAppearanceProperties. **/
	public WallAppearance3D(int renderingOrder, 
							int simpleAppearanceProperties, boolean backfaced) {
		super(renderingOrder,simpleAppearanceProperties,backfaced ? modelBackfaced : model);
	}
	
	/*============================================================
	Private Methods
	============================================================*/
	
	/** Creates the geometry model. **/
	private static Geometry createModel(	double width, 
											double height, 
											double depth,
											boolean backfaced) {
		final double w = width/2, h = height/2, d = depth/2;
		final TriangleStripArray ta = new TriangleStripArray(4,
											GeometryArray.COORDINATES +
											GeometryArray.NORMALS + 
											GeometryArray.TEXTURE_COORDINATE_2,
											new int[] {4});
		
		// Create the corners of the wall
		final Point3d tlb = new Point3d(-w,h,-d);
		final Point3d blb = new Point3d(-w,-h,-d);
		final Point3d trf = new Point3d(w,h,d);
		final Point3d brf = new Point3d(w,-h,d);
		
		// Generate texture coordinates
		final TexCoord2f tl = new TexCoord2f(0,1);
		final TexCoord2f tr = new TexCoord2f(1,1);
		final TexCoord2f bl = new TexCoord2f(0,0);
		final TexCoord2f br = new TexCoord2f(1,0);
		
		// Create wall
		final Point3d[] wall;
		final TexCoord2f[] texCoord;
		if (backfaced) {
			final Point3d[] wl = {blb,tlb,brf,trf};
			final TexCoord2f[] t = {bl,tl,br,tr};
			wall = wl;
			texCoord = t;
		} else {
			final Point3d[] wl = {blb,brf,tlb,trf};
			final TexCoord2f[] t = {bl,br,tl,tr};
			wall = wl;
			texCoord = t;
		}
		
		ta.setCoordinates(0, wall);
		ta.setTextureCoordinates(0, 0, texCoord);
		
		// Generate normals
		final GeometryInfo g = new GeometryInfo(ta);
		final NormalGenerator ng = new NormalGenerator();
		ng.generateNormals(g);
					
		return g.getGeometryArray();
	}
	

}
